package com.quiz.bis.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.quiz.bis.domain.bo.PaperStrategyBO;
import com.quiz.bis.domain.model.PaperStrategy;
import com.quiz.bis.domain.model.PaperTemplate;
import com.quiz.bis.domain.model.QuestionCategory;
import com.quiz.bis.domain.vo.PaperStrategyVO;
import com.quiz.bis.mapper.PaperStrategyMapper;
import com.quiz.bis.mapper.PaperTemplateMapper;
import com.quiz.bis.mapper.QuestionCategoryMapper;
import com.quiz.bis.service.IPaperStrategyService;
import com.quiz.bis.service.IQuestionCategoryService;
import com.quiz.common.core.domain.R;
import com.quiz.common.core.domain.model.LoginUser;
import com.quiz.common.exception.ServiceException;
import com.quiz.common.mybatis.core.page.PageQuery;
import com.quiz.common.mybatis.core.page.TableDataInfo;
import com.quiz.common.utils.SecurityUtils;
import com.quiz.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 组卷策略服务实现
 *
 * @author ahuan
 */
@Service
@RequiredArgsConstructor
public class PaperStrategyServiceImpl implements IPaperStrategyService {

    private final PaperStrategyMapper strategyMapper;
    private final PaperTemplateMapper templateMapper;
    private final QuestionCategoryMapper categoryMapper;

    @Override
    public TableDataInfo<PaperStrategy> pageStrategyList(PageQuery pageQuery, String name, Integer strategyType) {
        Page<PaperStrategy> page = strategyMapper.selectPage(pageQuery.build(),
                Wrappers.<PaperStrategy>lambdaQuery()
                        .like(StringUtils.isNotBlank(name), PaperStrategy::getName, name)
                        .eq(strategyType != null, PaperStrategy::getStrategyType, strategyType)
                        .eq(PaperStrategy::getDelFlag, 0)
        );
        return TableDataInfo.build(page);
    }

    @Override
    @Transactional
    public R<Long> createStrategy(PaperStrategyBO strategyBO) {
        // 验证策略名称
        if (StringUtils.isBlank(strategyBO.getName())) {
            return R.fail("策略名称不能为空");
        }

        // 检查名称是否已存在
        if (strategyMapper.exists(Wrappers.<PaperStrategy>lambdaQuery()
                .eq(PaperStrategy::getName, strategyBO.getName())
                .eq(PaperStrategy::getDelFlag, 0))) {
            return R.fail("策略名称已存在");
        }

        // 验证模板是否存在（如果是标准模板类型）
        if (strategyBO.getStrategyType() == 2 && strategyBO.getTemplateId() != null) {
            if (!templateMapper.exists(Wrappers.<PaperTemplate>lambdaQuery()
                    .eq(PaperTemplate::getId, strategyBO.getTemplateId())
                    .eq(PaperTemplate::getDelFlag, 0))) {
                return R.fail("关联的模板不存在");
            }
        }

        // 创建策略
        PaperStrategy strategy = BeanUtil.copyProperties(strategyBO, PaperStrategy.class);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        strategy.setCreateByName(loginUser.getUsername());

        // 获取知识点名称列表
        if (strategyBO.getKnowledgeConfig() != null) {
            List<Long> ids = Arrays.stream(JSONUtil.parseObj(strategyBO.getKnowledgeConfig())
                            .getJSONArray("knowledgePoints").toArray())
                    .map(obj -> Long.parseLong(obj.toString())).collect(Collectors.toList());
            if(CollUtil.isEmpty(ids)) throw new ServiceException("知识点不能为空");
            List<QuestionCategory> questionCategories = categoryMapper.selectBatchIds(ids);
            if (CollUtil.isNotEmpty(questionCategories)) {
                List<String> knowledgeName = questionCategories.stream().map(QuestionCategory::getName).collect(Collectors.toList());
                JSONObject entries = JSONUtil.parseObj(strategyBO.getKnowledgeConfig());
                entries.set("knowledgeNames", knowledgeName);
                strategy.setKnowledgeConfig(entries.toString());
            }
        }

        strategyMapper.insert(strategy);
        return R.ok(strategy.getId());
    }

    @Override
    public R<PaperStrategy> getStrategyDetail(Long strategyId) {
        PaperStrategy strategy = strategyMapper.selectById(strategyId);
        if (strategy == null || strategy.getDelFlag() == 1) {
            return R.fail("策略不存在或已删除");
        }
        return R.ok(strategy);
//        PaperStrategyVO strategyVO = BeanUtil.copyProperties(strategy, PaperStrategyVO.class);
//
        // 如果关联了模板，查询模板名称
//        if (strategy.getTemplateId() != null) {
//            PaperTemplate template = templateMapper.selectById(strategy.getTemplateId());
//            if (template != null) {
//                strategyVO.setTemplateName(template.getName());
//            }
//        }
//
//        return R.ok(strategyVO);
    }

    @Override
    @Transactional
    public R<Void> updateStrategy(PaperStrategyBO strategyBO) {
        if (strategyBO.getId() == null) {
            return R.fail("策略ID不能为空");
        }

        PaperStrategy strategy = strategyMapper.selectById(strategyBO.getId());
        if (strategy == null || strategy.getDelFlag() == 1) {
            return R.fail("策略不存在或已删除");
        }

        // 验证模板是否存在（如果是标准模板类型）
        if (strategyBO.getStrategyType() == 2 && strategyBO.getTemplateId() != null) {
            if (!templateMapper.exists(Wrappers.<PaperTemplate>lambdaQuery()
                    .eq(PaperTemplate::getId, strategyBO.getTemplateId())
                    .eq(PaperTemplate::getDelFlag, 0))) {
                return R.fail("关联的模板不存在");
            }
        }

        // 更新策略信息
        BeanUtil.copyProperties(strategyBO, strategy);
        strategyMapper.updateById(strategy);
        return R.ok();
    }

    @Override
    @Transactional
    public R<Void> deleteStrategy(Long strategyId) {
        PaperStrategy strategy = strategyMapper.selectById(strategyId);
        if (strategy == null || strategy.getDelFlag() == 1) {
            return R.fail("策略不存在或已删除");
        }

        // 逻辑删除
        strategy.setDelFlag(1);
        strategyMapper.updateById(strategy);
        return R.ok();
    }
}